package cn.edu.tju.elm.controller;

import cn.edu.tju.core.model.HttpResult;
import cn.edu.tju.core.model.ResultCodeEnum;
import cn.edu.tju.core.model.User;
import cn.edu.tju.elm.dto.FoodResponseDTO;
import cn.edu.tju.elm.dto.FoodUpdateDTO;
import cn.edu.tju.elm.mapper.FoodMapper;
import cn.edu.tju.elm.model.Food;
//import cn.edu.tju.elb.service.BusinessService;
//import cn.edu.tju.elb.service.FoodService;
import cn.edu.tju.core.security.service.UserService;
import cn.edu.tju.core.security.PermissionUtils;
import cn.edu.tju.elm.service.BusinessService;
import cn.edu.tju.elm.service.FoodService;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.*;

import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.util.List;
import java.util.Optional;

@RestController
@RequestMapping("/api/foods")
@Tag(name = "管理商品")
public class FoodController {
    @Autowired
    private UserService userService;

    @Autowired
    private FoodService foodService;

    @Autowired
    private BusinessService businessService;

    @Autowired
    private FoodMapper foodMapper;

    @Autowired
    private PermissionUtils permissionUtils;

    // 公共访问接口 - 无需认证
    @GetMapping("/public")
    @Operation(summary = "查询所有商品（公共访问）", description = "无需登录即可查看所有商品信息")
    public HttpResult<List<FoodResponseDTO>> getAllFoodsPublic(){
        try {
            List<Food> foods = foodService.getAllFoods();
            List<FoodResponseDTO> responseDTOs = foodMapper.foodsToResponseDTOs(foods);
            return HttpResult.success(responseDTOs);
        } catch (Exception e) {
            return HttpResult.failure(ResultCodeEnum.SERVER_ERROR, "查询商品失败: " + e.getMessage());
        }
    }

    @GetMapping("/public/{id}")
    @Operation(summary = "根据ID查询商品（公共访问）", description = "无需登录即可查看商品详情")
    public HttpResult<FoodResponseDTO> getFoodByIdPublic(@PathVariable Long id){
        try {
            Optional<Food> food = foodService.getFoodById(id);
            if (food.isPresent()) {
                FoodResponseDTO responseDTO = foodMapper.foodToResponseDTO(food.get());
                return HttpResult.success(responseDTO);
            } else {
                return HttpResult.failure(ResultCodeEnum.NOT_FOUND, "商品不存在");
            }
        } catch (Exception e) {
            return HttpResult.failure(ResultCodeEnum.SERVER_ERROR, "查询商品失败: " + e.getMessage());
        }
    }

    @GetMapping("/public/business/{businessId}")
    @Operation(summary = "根据店铺ID查询商品（公共访问）", description = "无需登录即可查看店铺的所有商品")
    public HttpResult<List<FoodResponseDTO>> getFoodsByBusinessIdPublic(@PathVariable Long businessId){
        try {
            List<Food> foods = foodService.getFoodsByBusinessId(businessId);
            List<FoodResponseDTO> responseDTOs = foodMapper.foodsToResponseDTOs(foods);
            return HttpResult.success(responseDTOs);
        } catch (Exception e) {
            return HttpResult.failure(ResultCodeEnum.SERVER_ERROR, "查询商品失败: " + e.getMessage());
        }
    }

    @GetMapping("/public/search")
    @Operation(summary = "搜索商品（公共访问）", description = "无需登录即可搜索商品")
    public HttpResult<List<FoodResponseDTO>> searchFoodsPublic(@RequestParam(required = false) String name,
                                                               @RequestParam(required = false) BigDecimal minPrice,
                                                               @RequestParam(required = false) BigDecimal maxPrice,
                                                               @RequestParam(required = false) Boolean onSale){
        try {
            List<Food> foods = foodService.searchFoods(name, minPrice, maxPrice, onSale);
            List<FoodResponseDTO> responseDTOs = foodMapper.foodsToResponseDTOs(foods);
            return HttpResult.success(responseDTOs);
        } catch (Exception e) {
            return HttpResult.failure(ResultCodeEnum.SERVER_ERROR, "搜索商品失败: " + e.getMessage());
        }
    }

    // 需要认证的接口 - 使用@PreAuthorize进行权限控制
    @GetMapping("/{id}")
    @PreAuthorize("hasAuthority('ADMIN') or @permissionUtils.canAccessBusinessData(@foodService.getFoodById(#id).get().getBusiness().getBusinessOwner().getId())")
    @Operation(summary = "返回查询到的一条商品记录", method = "GET")
    public HttpResult<FoodResponseDTO> getFoodById(@PathVariable Long id){
        try {
            Optional<Food> food = foodService.getFoodById(id);
            if (food.isPresent()) {
                FoodResponseDTO responseDTO = foodMapper.foodToResponseDTO(food.get());
                return HttpResult.success(responseDTO);
            } else {
                return HttpResult.failure(ResultCodeEnum.NOT_FOUND, "商品不存在");
            }
        } catch (Exception e) {
            return HttpResult.failure(ResultCodeEnum.SERVER_ERROR, "查询商品失败: " + e.getMessage());
        }
    }

    @GetMapping("")
    @PreAuthorize("hasAnyAuthority('ADMIN','BUSINESS','USER')")
    @Operation(summary = "返回查询到的所有商品记录")
    public HttpResult<List<FoodResponseDTO>> getAllFoods(@RequestParam(name = "business", required = false) Long businessId,
                                              @RequestParam(name = "order", required = false) Long orderId){
        try {
            List<Food> foods;
            if (businessId != null) {
                foods = foodService.getFoodsByBusinessId(businessId);
            } else {
                foods = foodService.getAllFoods();
            }
            List<FoodResponseDTO> responseDTOs = foodMapper.foodsToResponseDTOs(foods);
            return HttpResult.success(responseDTOs);
        } catch (Exception e) {
            return HttpResult.failure(ResultCodeEnum.SERVER_ERROR, "查询商品失败: " + e.getMessage());
        }
    }

    @GetMapping("/search")
    @PreAuthorize("hasAnyAuthority('ADMIN','BUSINESS','USER')")
    @Operation(summary = "根据商品名称搜索商品")
    public HttpResult<List<FoodResponseDTO>> searchFoodsByName(@RequestParam String name){
        try {
            List<Food> foods = foodService.getFoodsByNameContaining(name);
            List<FoodResponseDTO> responseDTOs = foodMapper.foodsToResponseDTOs(foods);
            return HttpResult.success(responseDTOs);
        } catch (Exception e) {
            return HttpResult.failure(ResultCodeEnum.SERVER_ERROR, "搜索商品失败: " + e.getMessage());
        }
    }

    @GetMapping("/price-range")
    @PreAuthorize("hasAnyAuthority('ADMIN','BUSINESS','USER')")
    @Operation(summary = "根据价格范围查询商品")
    public HttpResult<List<FoodResponseDTO>> getFoodsByPriceRange(@RequestParam BigDecimal minPrice, 
                                                                  @RequestParam BigDecimal maxPrice){
        try {
            List<Food> foods = foodService.getFoodsByPriceRange(minPrice, maxPrice);
            List<FoodResponseDTO> responseDTOs = foodMapper.foodsToResponseDTOs(foods);
            return HttpResult.success(responseDTOs);
        } catch (Exception e) {
            return HttpResult.failure(ResultCodeEnum.SERVER_ERROR, "查询商品失败: " + e.getMessage());
        }
    }

    @GetMapping("/on-sale")
    @PreAuthorize("hasAnyAuthority('ADMIN','BUSINESS','USER')")
    @Operation(summary = "查询在售商品")
    public HttpResult<List<FoodResponseDTO>> getOnSaleFoods(@RequestParam(name = "business", required = false) Long businessId){
        try {
            List<Food> foods = foodService.getOnSaleFoods(businessId);
            List<FoodResponseDTO> responseDTOs = foodMapper.foodsToResponseDTOs(foods);
            return HttpResult.success(responseDTOs);
        } catch (Exception e) {
            return HttpResult.failure(ResultCodeEnum.SERVER_ERROR, "查询在售商品失败: " + e.getMessage());
        }
    }

    @GetMapping("/business/{businessId}")
    @PreAuthorize("hasAnyAuthority('ADMIN','BUSINESS','USER')")
    @Operation(summary = "根据店铺ID查询商品")
    public HttpResult<List<FoodResponseDTO>> getFoodsByBusiness(@PathVariable Long businessId){
        try {
            List<Food> foods = foodService.getFoodsByBusinessId(businessId);
            List<FoodResponseDTO> responseDTOs = foodMapper.foodsToResponseDTOs(foods);
            return HttpResult.success(responseDTOs);
        } catch (Exception e) {
            return HttpResult.failure(ResultCodeEnum.SERVER_ERROR, "查询店铺商品失败: " + e.getMessage());
        }
    }

    @PostMapping("")
    @PreAuthorize("hasAnyAuthority('ADMIN','BUSINESS')")
    @Operation(summary = "增加商品")
    public HttpResult<FoodResponseDTO> addFood(@RequestBody Food food){
        try {
            User user = userService.getUserWithAuthorities().get();
            LocalDateTime now = LocalDateTime.now();
            food.setCreator(user.getId());
            food.setCreateTime(now);
            food.setUpdater(user.getId());
            food.setUpdateTime(now);
            food.setDeleted(false);
            Food f = foodService.addFood(food);
            FoodResponseDTO responseDTO = foodMapper.foodToResponseDTO(f);
            return HttpResult.success(responseDTO);
        } catch (Exception e) {
            return HttpResult.failure(ResultCodeEnum.SERVER_ERROR, "添加商品失败: " + e.getMessage());
        }
    }

    @PutMapping("/{id}")
    @PreAuthorize("hasAuthority('ADMIN') or (hasAuthority('BUSINESS') and @permissionUtils.canAccessBusinessData(@foodService.getFoodById(#id).get().getBusiness().getBusinessOwner().getId()))")
    @Operation(summary = "修改商品信息")
    public HttpResult<FoodResponseDTO> updateFood(@PathVariable Long id, @RequestBody FoodUpdateDTO foodUpdateDTO){
        try {
            User user = userService.getUserWithAuthorities().get();
            Food food = foodMapper.updateDtoToFood(foodUpdateDTO);
            food.setId(id);
            food.setUpdater(user.getId());
            food.setUpdateTime(LocalDateTime.now());
            Food updatedFood = foodService.updateFood(food);
            FoodResponseDTO responseDTO = foodMapper.foodToResponseDTO(updatedFood);
            return HttpResult.success(responseDTO);
        } catch (Exception e) {
            return HttpResult.failure(ResultCodeEnum.SERVER_ERROR, "修改商品失败: " + e.getMessage());
        }
    }

    @DeleteMapping("/{id}")
    @PreAuthorize("hasAnyAuthority('ADMIN')")
    @Operation(summary = "删除商品", description = "只有管理员有权限删除商品")
    public HttpResult<String> deleteFood(@PathVariable Long id){
        try {
            foodService.deleteFood(id);
            return HttpResult.success("删除成功");
        } catch (Exception e) {
            return HttpResult.failure(ResultCodeEnum.SERVER_ERROR, "删除商品失败: " + e.getMessage());
        }
    }

    @PatchMapping("/{id}")
    @PreAuthorize("hasAuthority('ADMIN') or (hasAuthority('BUSINESS') and @permissionUtils.canAccessBusinessData(@foodService.getFoodById(#id).get().getBusiness().getBusinessOwner().getId()))")
    @Operation(summary = "部分修改商品信息")
    public HttpResult<FoodResponseDTO> partiallyUpdateFood(@PathVariable Long id, @RequestBody FoodUpdateDTO foodUpdateDTO){
        try {
            User user = userService.getUserWithAuthorities().get();
            Optional<Food> existingFood = foodService.getFoodById(id);
            if (existingFood.isPresent()) {
                Food foodToUpdate = existingFood.get();
                // 只更新非空字段
                if (foodUpdateDTO.getFoodName() != null) {
                    foodToUpdate.setFoodName(foodUpdateDTO.getFoodName());
                }
                if (foodUpdateDTO.getFoodExplain() != null) {
                    foodToUpdate.setFoodExplain(foodUpdateDTO.getFoodExplain());
                }
                if (foodUpdateDTO.getFoodImg() != null) {
                    foodToUpdate.setFoodImg(foodUpdateDTO.getFoodImg());
                }
                if (foodUpdateDTO.getFoodPrice() != null) {
                    foodToUpdate.setFoodPrice(foodUpdateDTO.getFoodPrice());
                }
                if (foodUpdateDTO.getRemarks() != null) {
                    foodToUpdate.setRemarks(foodUpdateDTO.getRemarks());
                }
                if (foodUpdateDTO.getOnSale() != null) {
                    foodToUpdate.setOnSale(foodUpdateDTO.getOnSale());
                }
                if (foodUpdateDTO.getBusinessId() != null) {
                    Food updateData = foodMapper.updateDtoToFood(foodUpdateDTO);
                    foodToUpdate.setBusiness(updateData.getBusiness());
                }
                // 支持修改deleted属性
                if (foodUpdateDTO.getDeleted() != null) {
                    foodToUpdate.setDeleted(foodUpdateDTO.getDeleted());
                }
                foodToUpdate.setUpdater(user.getId());
                foodToUpdate.setUpdateTime(LocalDateTime.now());
                Food updatedFood = foodService.updateFood(foodToUpdate);
                FoodResponseDTO responseDTO = foodMapper.foodToResponseDTO(updatedFood);
                return HttpResult.success(responseDTO);
            } else {
                return HttpResult.failure(ResultCodeEnum.NOT_FOUND, "商品不存在");
            }
        } catch (Exception e) {
            return HttpResult.failure(ResultCodeEnum.SERVER_ERROR, "部分修改商品失败: " + e.getMessage());
        }
    }
}
